/*****************************************************************************
 * frame.h: frame handling
 *****************************************************************************
 * Copyright (C) 2003-2018 x264 project
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Loren Merritt <lorenm@u.washington.edu>
 *          Fiona Glaser <fiona@x264.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at licensing@x264.com.
 *****************************************************************************/

#ifndef X264_FRAME_H
#define X264_FRAME_H

/* number of pixels past the edge of the frame, for motion estimation/compensation */
#define PADH 32
#define PADV 32

typedef struct x264_frame
{
    /*在x264库中，视频帧数据被存储在一块内存缓冲区中，x264_frame_t结构体的base成员变量则指向这个缓冲区的起始地址。这个缓冲区包含了该帧的所有像素数据和其他相关信息（如PTS、类型等）。

在进行编码过程中，视频帧数据会被分割成多个宏块（macroblock，MB）进行H.264/AVC编码。编码后的比特流经过打包、传输等过程后再被重组解码为视频帧。此时，解码器需要知道每个宏块的位置、尺寸和类型等信息，x264_frame_t结构体中的成员变量就存储了这些信息。

因此，x264_frame_t结构体的base成员变量就是指向存储当前视频帧的缓冲区的起始地址，用于在编码和解码时确定保存帧数据的内存区域。 */
    uint8_t *base;       /* Base pointer for all malloced data in this frame. */
    /*在x264中，i_poc是x264_picture_t中的一个成员变量，用于表示该图像的Poc值。Poc值是用于确定图像显示顺序的重要参数，也是H.264/AVC编码中的一个重要概念。

Poc值全称为Picture Order Count，即图像显示顺序计数。在x264编码器中，编码器首先会根据帧类型（I帧、P帧、B帧）和GOP（Group Of Pictures）结构设计一个显示顺序，显示顺序中的每一帧都会被分配一个Poc值。其中，Poc值越小表示该图像越靠前，Poc相同的图像按照先来后到的顺序进行显示。通过Poc值的分配，可以保证x264编码器生成的视频帧显示顺序的正确性。

因此，在x264_picture_t中的i_poc值表示该帧图像的Poc值，用于确定显示顺序并确保视频解码的正确性。*/
    int     i_poc;
    /*在x264中，i_delta_poc[2]是x264_picture_t中的一个成员变量，用于表示该图像相对于以前图像的Poc差值。即表示当前帧的Poc与之前参考帧的Poc之差。其中，i_delta_poc[0]表示相对于前一个参考帧的Poc差值，i_delta_poc[1]表示相对于参考帧的Poc差值。

在H.264/AVC编码中，参考帧序列在解码时用于重构显式B帧。因为B帧需要使用前后参考帧中的像素进行预测，因此，编码时需要指定参考帧列表并计算Poc值。i_delta_poc[2]就是记录当前图像的Poc与参考帧Poc之差，方便在解码时按正确的顺序重构B帧。

例如，编码P1和P2两帧及其之间的一帧B1，当解码B1时，需要将其重构为P1和P2之间的帧。在解码B1时，就需要知道P1和P2的Poc值和B1相对于P1和P2的Poc差值。因此，i_delta_poc[2]同样是H.264/AVC编码中重要的概念，用于实现B帧的解码和重构。*/
    int     i_delta_poc[2];
    /*在x264中，i_type是x264_picture_t中的一个成员变量，用于表示该视频帧的帧类型。H.264/AVC中定义了三种帧类型：I帧（Intra Frame）、P帧（Predictive Frame）和B帧（Bi-directional Prediction Frame），每种帧类型都有各自的编码方式和特点。

具体来说，i_type为0表示当前帧为P帧，1表示当前帧为B帧，2表示当前帧为I帧。对于P帧，其编码使用的是之前一帧的像素数据进行预测；对于B帧，编码使用之前和之后的帧的像素数据进行预测；对于I帧，编码会重置编码的参考图像，不使用之前的像素数据进行预测，而是使用自己的帧内像素数据。*/
    int     i_type;
    /*x264_frame_t中的int i_forced_type表示强制帧类型。在视频编码中，帧类型分为三种：I帧、P帧、B帧。其中I帧是关键帧，也叫做帧内编码，每个I帧都是一个独立的图像帧，P帧则是预测编码帧，B帧则是双向预测编码帧。在一些编码器中，可以通过设置强制帧类型来指定编码器编码的帧类型，i_forced_type就是用来表示这个设置的值。具体来说，i_forced_type的取值有以下几种：

1. X264_TYPE_AUTO：自动选择帧类型
2. X264_TYPE_AUTO_SELECT：自动选择I帧或P帧
3. X264_TYPE_I：强制选择I帧
4. X264_TYPE_P：强制选择P帧
5. X264_TYPE_B：强制选择B帧

通过设置i_forced_type可以在一定程度上影响编码后的视频质量和编码效率。*/
    int     i_forced_type;
    int     i_qpplus1;
    int64_t i_pts;
    int64_t i_dts;
    /*x264_frame_t中的int64_t i_reordered_pts是一个64位整型变量，用来表示已经重新排序后的帧的PTS（Presentation Timestamp）值。PTS是一种时间戳，表示当前帧应该在视频播放中的时间位置。在视频编码中，由于P帧和B帧的存在，编码后的帧的PTS值可能会出现乱序。i_reordered_pts就是用来记录在经过重新排序后，当前帧正确的PTS值。当然，如果当前帧是I帧，则不需要重新排序PTS值。

需要注意的是，i_reordered_pts只记录了重新排序后的PTS值，它并不是帧的实际PTS值。在使用i_reordered_pts前，应该先进行相关的PTS补偿操作，以得到帧的真实PTS值。*/
    int64_t i_reordered_pts;

    /*在x264_frame_t结构体中，int64_t i_duration和float f_duration分别表示帧的持续时间，具体含义如下：

- i_duration：表示帧的持续时间（时长），单位为时钟周期。时钟周期是某个时钟信号的一个完整循环所需的时间，它的具体数值取决于使用的时钟源和时钟频率。i_duration为整型，可以精确表示所有时长（毫秒级以上，包括纳秒和微秒），但不能表示小数。
- f_duration：表示帧的持续时间（时长），单位为秒。f_duration为浮点型，可以表示小数，但可能存在舍入误差。同时，由于浮点数的精度限制，对于时长非常小（毫秒以下）的帧，f_duration可能无法精确表示。

在实际使用中需要根据具体情况选择合适的变量类型。如果需要精确表示所有的时长，建议使用i_duration；如果对于精度有一定要求，但误差能够接受，或者时间较短，建议使用f_duration。*/
    int64_t i_duration;  /* in SPS time_scale units (i.e 2 * timebase units) used for vfr */
    float   f_duration;  /* in seconds */
    /*i_cpb_duration是x264_frame_t结构体中的一个整型变量，表示当前帧输出后编码器缓冲区（CPB，Coding Picture Buffer）中的时长，单位为毫秒。CPB是在编码器中用来存放编码帧的缓冲区，它的大小和使用方式由标准定义。

在视频编码中，为了保证码流的稳定性和兼容性，在编码过程中需要对码流进行控制，以使得码流符合标准规范。其中一个重要因素是CPB，编码器的输出码流必须满足CPB的大小和使用速率限制。i_cpb_duration表示当前帧输出后，CPB缓冲区中的时长，能够帮助编码器对码流进行精细的控制。通过控制i_cpb_duration的值，可以调整编码器输出的码率和码流稳定性。*/
    int64_t i_cpb_duration;
    /*i_cpb_delay是x264_picture_t结构体以及x264_nal_t结构体中的一个整型变量，表示当前帧的编码延迟，单位为毫秒。具体来说，编码器在进行视频压缩时需要将待编码的帧缓冲一段时间，以便利用预测模式等技术来取得更好的压缩效果。而i_cpb_delay就是用来记录这个缓冲时间的，它可以帮助编码器更加精确的控制编码的输出延迟。

在H.264/AVC视频编码标准中，编码器的输出应该符合CPB（Coding Picture Buffer）缓冲的规定，以实现码流的稳定性和可读性。i_cpb_delay的值可以用来计算出当前帧的输出时间，从而方便编码器根据CPB的大小和使用速率限制，来调整帧的码率和输出时间，以满足标准的要求。需要注意的是，i_cpb_delay只是一个参考值，具体的延迟时间受到编码器设置和帧类型等因素的影响，可能会有所偏差。*/
    int64_t i_cpb_delay; /* in SPS time_scale units (i.e 2 * timebase units) */
    /*i_dpb_output_delay是x264_picture_t结构体中的一个整型变量，表示当前帧的DPB（Decoded Picture Buffer）输出时的延迟，单位为毫秒。DPB是用来存储解码器当前解码的帧的缓冲区，编码器在进行B帧编码时需要查找DPB以取得参考帧的信息。i_dpb_output_delay就是用来记录B帧编码过程中，参考帧在DPB中的延迟时间。如果当前帧不是B帧，则i_dpb_output_delay值为0。

在x264的B帧编码中，i_dpb_output_delay与i_cpb_delay值不同，具体的区别如下：

- i_cpb_delay是指编码器在对帧进行编码后，输出码流到达解码器的时间（即编码延迟），它是由编码器控制的。i_cpb_delay的值可以影响编码器的码率和码流稳定性。
- 而i_dpb_output_delay则是指当前帧在解码器中被正式解码输出的时间（即输出延迟），它是由解码器控制的。i_dpb_output_delay的值可以影响解码器的速度和解码延迟。

需要注意的是，i_dpb_output_delay值可能会随着解码器的设置和实现不同而有所变化，具体取值可能会有一定的误差。*/
    int64_t i_dpb_output_delay;
    x264_param_t *param;

    // 显示顺序的帧序号？？
    int     i_frame;     /* Presentation frame number */
    // 已编码的帧数
    int     i_coded;     /* Coded frame number */
    // 场序号？？
    int64_t i_field_cnt; /* Presentation field count */
    // 帧的实际序号，由于B帧，可能和i_frame会不一样
    int     i_frame_num; /* 7.4.3 frame_num */
    /*b_kept_as_ref是x264_frame_t结构体中的一个布尔型变量，用于表示当前帧是否被保留为参考帧（Reference Frame）。在视频编码中，参考帧通常用于进行预测编码（Predictive Coding），以提高编码效率和输出质量。如果当前帧被保留为参考帧，则它可以被后续的帧用于参考和预测。

具体来说，当编码器进行帧编码时，会根据当前帧的类型和内容，选择一定数量的参考帧用于进行预测编码操作。对于某些高复杂度或者关键帧（I帧），编码器可能需要将当前帧自己保留为参考帧，以供后续的P帧或B帧进行参考和预测。这个时候，b_kept_as_ref的值就为True，表示当前帧是一帧参考帧。

需要注意的是，参考帧的数量和选择对编码效率和输出质量有着重要影响，因此编码器会根据当前帧的类型和内容自动进行参考帧选择和替换。b_kept_as_ref的取值不应该被手动修改或者用作编码策略的参考依据。
*/
    int     b_kept_as_ref;
    /*在x264_frame_t结构体中，i_pic_struct是一个整型变量，表示当前帧的图像结构类型（Picture Structure）。图像结构类型用于描述视频帧的扫描方式和编码结构，通常有3种类型：

- FRAME_PICTURE: 帧图像，也就是普通的整帧，没有拆分成场或者其他类型的子帧。
- TOP_FIELD: 顶场，表示视频帧被分成2个相邻的上下场。这种类型的图像结构通常用于交错扫描的视频编码中。
- BOTTOM_FIELD: 底场，与上场相反，表示视频帧被分成2个相邻的下上场。这种类型的图像结构也主要用于交错扫描的视频编码中。*/
    // 1：逐行扫描
    // 4：顶场优先
    // 5：底场优先
    int     i_pic_struct;
    int     b_keyframe;
    /*x264_frame_t是x264库中的结构体，用于存储编码后的视频帧数据。其中，b_fdec是一个用于标识当前帧是否是一个参考帧（I帧、P帧或B帧）的标记位，它的具体含义如下：

- 当b_fdec为1时，表示该帧是一个参考帧（参考帧包括：I帧、P帧和一些特殊的B帧），也就是说该帧的图像数据能够被其他帧参考，用于解码。

- 当b_fdec为0时，表示该帧不是一个参考帧（称为“非参考帧”或“预测帧”），不能被其他帧参考，用于预测。

在视频编码中，参考帧是用于预测其他帧的图像数据的。x264编码器会根据视频帧的内容选择I帧、P帧和B帧进行编码，以尽可能压缩数据量并保持图像质量。在x264编码器中，B帧是双向参考帧，需要使用前后两个参考帧进行预测。

因此，在解码时，如果需要解码当前帧，就需要先解码它所依赖的参考帧。而b_fdec就是用于标记当前帧是否是一个参考帧，以便在解码时进行相关操作*/
/*b_kept_as_ref是x264_picture_t结构体中的一个标志位，用于标记当前帧是否会被作为参考帧保留。而b_fdec是x264_frame_t结构体中的一个标记位，用于标记当前帧是否是一个参考帧（I帧、P帧或B帧）。

在x264编码中，会先对视频帧进行编码，生成压缩后的数据，然后再对压缩后的数据进行打包（packetization），每个包包含一个或多个NALU（Network Abstraction Layer Unit）。

在打包时，对于I帧和P帧，会将它们打包为单个NALU；而对于B帧，由于它需要参考前后两个帧，因此会将它们打包为多个NALU，每个NALU内部包含该帧的部分数据和相关的参考信息。

对于B帧，在打包时需要标记哪些NALU是可以作为参考帧保留的。而这个标记就是通过b_kept_as_ref来实现的。

在解码时，只有被作为参考帧保留的NALU才能用来解码其他帧。而b_fdec是为了标记当前帧是否是一个参考帧，以便在解码时进行相关操作。因此，b_kept_as_ref和b_fdec在标记参考帧时功能是相似的，但它们所标记的对象和标记的方式是不同的。*/
    // 是解码帧还是编码帧
    uint8_t b_fdec;
    /*x264_picture_t结构体中的b_last_minigop_bframe标志用于控制x264 ME（Motion Estimation）缓存刷新的行为。ME是x264中一个重要的编码优化技术，用于在压缩过程中预测运动矢量和编码残差，以便更好地压缩图像。

在x264中，ME缓存（ME buffer）是用于保存之前帧的运动矢量和编码残差的缓存区。当使用B帧进行编码时，ME缓存需要在GOP（Group of Pictures）之间进行刷新，以便之后的B帧能够正确预测它们所需要的运动矢量和编码残差。

b_last_minigop_bframe标志表示当前帧是否是GOP中的最后一个B帧。如果当前帧是最后一个B帧，那么在ME缓存刷新时，需要对ME缓存进行一些额外的处理，以满足之后B帧的运动矢量和编码残差的预测需求。这个额外处理的方式取决于具体的ME策略和编码设置，可能会对编码效率、码率和图像质量产生影响。

需要注意的是，b_last_minigop_bframe标志只在GOP中使用B帧时才会有用，对于只使用I帧和P帧的GOP，该标志没有任何作用。*/
    uint8_t b_last_minigop_bframe; /* this frame is the last b in a sequence of bframes */
    /*i_bframes是Video Coding Standard规定的GOP结构中的一个参数，表示在当前编码序列中，连续的B帧数最大值。例如，如果i_bframes为2，那么编码器允许在两个P帧之间插入至多两个B帧。

在视频编码中，一个GOP由一系列相互依赖的帧组成。这些帧可以是I帧（关键帧）、P帧（预测帧）和B帧（双向预测帧）。其中，I帧是最基本的关键帧，P帧可以从前一帧（I帧或P帧）进行预测，B帧则可以从前后两帧（I帧或P帧）进行预测。

在x264编码器中，i_bframes参数以及其他的编码参数会影响GOP的结构和每帧的码率分配。这些参数可以通过调优来获得更好的视频质量和编码效率：

- i_bframes：表示最大B帧数。如果设置过大，会影响编码速度和码率分配；如果设置过小，会影响画质。

- i_keyint_max：表示最大关键帧间隔。过大的间隔会导致I帧与前面的帧差别过大，并影响视频的可压缩性；过小的间隔会增加I帧的数量，造成编码效率低下。

- i_frame_reference：表示参考帧的最大数量。增大参考帧数可以提高压缩比和图像质量，但会影响编码速度和码率分配。

根据实际应用需求，需要合理调整这些参数以获得最佳的编码效果。*/
    uint8_t i_bframes;   /* number of bframes following this nonb in coded order */
    /*x264_frame_t中的float f_qp_avg_rc表示该帧经过码率控制后的平均量化参数。在x264中，码率控制是一种通过调整量化参数来控制输出比特率的技术。因此，f_qp_avg_rc可以反映出编码器在控制输出比特率时所采取的调整策略和效果。*/
    float   f_qp_avg_rc; /* QPs as decided by ratecontrol */
    /*x264_frame_t中的float f_qp_avg_aq表示带自适应量化（AQ）的情况下，该帧的平均量化参数。自适应量化是一种通过对不同部分进行不同的量化降低失真并且提高编码效率的技术。因此，f_qp_avg_aq可以反映出编码器在采用自适应量化策略时帧的平均量化参数，以及自适应量化技术对编码效率和失真率的影响。*/
    float   f_qp_avg_aq; /* QPs as decided by AQ in addition to ratecontrol */
    /*x264_frame_t中的float f_crf_avg表示该帧在CRF（Constant Rate Factor）模式下的平均码率控制系数。CRF模式是一种基于视觉质量的码率控制方式，它尝试在给定的视觉质量下尽可能地减少编码比特率。因此，f_crf_avg可以反映出编码器在CRF模式下采用的码率控制策略，以及该帧所得到的码率控制系数。这个系数的具体取值在编码时可以调整以达到不同的视觉质量要求。*/
    float   f_crf_avg;   /* Average effective CRF for this frame */
    /*在H.264/AVC编码标准中，每一个帧都有一个POC（Picture Order Count）值，用于指示该帧的显示顺序。在x264中，i_poc_l0ref0表示该帧的POC值所依赖的L0参考帧（正向参考帧）的POC值。这个值的具体含义是该帧的POC值相对于L0参考帧的POC值的差值。L0参考帧是解码该帧时需要用到的参考帧之一。因此，i_poc_l0ref0可以用于确定该帧解码时所需要的L0参考帧的POC值，从而计算出该帧的显示顺序。*/
    int     i_poc_l0ref0; /* poc of first refframe in L0, used to check if direct temporal is possible */

    /* YUV buffer */
    // 颜色空间（color space）是指用于表示颜色和亮度的数值范围及其处理方式。x264支持多种颜色空间，如YUV、RGB等。在x264编码中，该值指示该帧使用的颜色空间，例如 i_csp=0 表示 YUV420颜色空间。
    int     i_csp; /* Internal csp */
    // 一个视频帧可以按照颜色空间的不同分成几个平面来处理，例如YUV420颜色空间就分成了亮度平面（Y plane）和两个色度平面（U plane和V plane）三个平面。i_plane值表示该帧中需要处理的平面数量。x264编码器中平面的顺序为：YUV420色彩空间为 Y,U,V；YUV422色彩空间为 Y,U,V；YUY2色彩空间为 Y,U,Y,V；RGB24色彩空间就只有一个平面。每个平面都可独立处理，以提高编码效率。
    int     i_plane;
    // 表示每个平面行数据占用内存的大小，也称为行间距（stride）。例如，在YUV420格式下，由于U和V平面是下采样的，其宽度只有亮度平面的一半，因此需要多留出一些空间，使得每行数据占用的字节数相同。i_stride[i]表示第i个平面的行间距（即每行数据在内存中的字节数），有时也称为pitch或者byte-per-line。
    int     i_stride[3];
    // 表示每个平面的宽度，以像素（pixel）为单位，即每行的像素数。通常，i_width对于三个平面会有不同的值。例如，在YUV420格式下，亮度平面的宽度等于视频的宽度，而色度平面的宽度只有亮度平面的一半，即i_width[0]=W，i_width[1]=i_width[2]=W/2，其中W为该帧的宽度。
    int     i_width[3];
    // 表示每个平面的高度，以行（line）为单位。通常，i_lines对于三个平面会有不同的值。例如，在YUV420格式下，亮度平面的高度等于视频的高度，而色度平面的高度只有亮度平面的一半，即i_lines[0]=H，i_lines[1]=i_lines[2]=H/2，其中H为该帧的高度。
    int     i_lines[3];

    /*这些参数是x264编码器中与低分辨率（low resolution）有关的参数，含义如下：

1. i_stride_lowres：表示低分辨率下每个平面行数据占用内存的大小。低分辨率下的行间距与原始分辨率相比通常会减少，从而节省内存开销。

2. i_width_lowres：表示低分辨率下每个平面的宽度，以像素（pixel）为单位。

3. i_lines_lowres：表示低分辨率下每个平面的高度，以行（line）为单位。与i_width_lowres一样，i_lines_lowres通常与原始分辨率相比会减少，以节省内存开销。

在一些应用场景中（如实时视频传输、移动设备视频编码等），低分辨率编码可以加快编码速度、减少码率、降低功耗和延长电池寿命等。x264的低分辨率编码采用了下采样的方式，将高分辨率原始帧降采样成低分辨率，从而得到低分辨率的编码结果。x264会在编码实现中自动计算低分辨率相关参数。*/
    int     i_stride_lowres;
    int     i_width_lowres;
    int     i_lines_lowres;

    // 包含编码帧所有平面的指针数组。对于每个平面i，plane[i]指向该平面数据的首地址。例如，在YUV420格式下，plane[0]指向亮度平面数据的首地址，而plane[1]和plane[2]分别指向U和V平面数据的首地址。
    pixel *plane[3];
    // 和plane[3]类似，只不过是用于针对帧场（frame-field）编码的场（field）数据。
    pixel *plane_fld[3];
    // 一个二维数组，表示帧中某个平面在进行缩放、人工增强或者锐化处理后的数据。具体来说，filtered[i][0]表示该平面原始数据，而filtered[i][1]、filtered[i][2]、filtered[i][3]分别表示该平面沿水平、垂直和对角线方向的滤波后的数据。
    // 半像素，1/4像素
    // 3表示yuv分量，4：plane[0], H, V, HV
    pixel *filtered[3][4]; /* plane[0], H, V, HV */
    // 和filtered[3][4]类似，只不过是用于针对帧场编码的场数据。
    pixel *filtered_fld[3][4];
    // 表示低分辨率下的帧数据。lowres[0]表示低分辨率下的原始帧数据，而lowres[1]、lowres[2]、lowres[3]分别表示低分辨率下的帧数据沿水平、垂直和对角线方向的滤波后的数据。
    pixel *lowres[4]; /* half-size copy of input frame: Orig, H, V, HV */
    // 积分图（integral image）数据指针，用于针对is_keyframe（即该帧是否是关键帧）为1的帧计算积分图。积分图可以加速像素值的统计和滤波计算。
    uint16_t *integral;

    /* for unrestricted mv we allocate more data than needed
     * allocated data are stored in buffer */
    /*用于存储编码器中不同缓存的指针数组。其中buffer[0]指向原始数据的缓存，buffer[1]、buffer[2]和buffer[3]分别用于存储沿水平、垂直和对角线方向的滤波后的数据。*/
    pixel *buffer[4];
    // 和buffer[4]类似，只不过是用于针对帧场（frame-field）编码的场（field）数据。
    pixel *buffer_fld[4];
    // 表示低分辨率时缩小图像的数据缓存。低分辨率编码是一种常用的优化方式，可以加速编码过程。buffer_lowres用于存储经过下采样后的缩小数据。
    pixel *buffer_lowres;

    /*x264_frame_t结构体中的weight[X264_REF_MAX][3]是一个二维数组，其中X264_REF_MAX是参考帧的最大数量，3是三个通道（Y、U、V）。这个数组用于存储编码时使用的加权矩阵，以实现对像素值进行加权。加权矩阵是为了提高编码质量，通常在场景中出现不同的光照条件或者肤色时，会使用加权矩阵对部分图像进行加权，以提高图像的质量。*/
    x264_weight_t weight[X264_REF_MAX][3]; /* [ref_index][plane] */
    /*pixel *weighted[X264_REF_MAX]是x264中编码时用来存储加权后像素值的指针数组。其中X264_REF_MAX是参考帧的最大数量。在编码过程中，如果使用了加权预测模式，就会根据加权矩阵将当前帧的像素值加权得到加权后的像素值，这些加权后的像素值就会被存储在weighted数组中。在后续的编码过程中，会使用这些加权后的像素值来进行预测和编码。*/
    pixel *weighted[X264_REF_MAX]; /* plane[0] weighted of the reference frames */
    /*int b_duplicate是x264中用于控制编码过程中的复制模式的标志位。当b_duplicate为1时，表示编码器将在编码过程中检测并复制相邻的块，以增加视频的编码效率。复制模式通常用于动态场景下，当相邻的块相似度较高时，可以通过复制块的方式来减少编码数据量。但是复制模式可能会增加解码时的计算复杂度，所以需要在编码效率和解码复杂度之间进行权衡，根据具体应用场景进行选择。*/
    int b_duplicate;
    /*struct x264_frame *orig; 是 x264_picture_t 结构体中的一个成员变量。这个结构体用来表示一帧图像。

orig 是一帧参考帧的指针，因为在编解码过程中，会涉及到参考帧的使用。对于视频编码来说，为了提高压缩效率，通常会将当前帧与之前的参考帧进行比较，找到最相似的参考帧，并将它们之间的差异进行编码。当要编码一帧新的视频时，需要事先准备好之前的参考帧，orig 就是一个指向参考帧的指针，用来保存之前编码过的一帧图像的原始数据。获取到这个参考帧之后，就可以用它来计算当前帧和参考帧之间的差异并进行编码。*/
    struct x264_frame *orig;

    /* motion data */
    /*用于存储一个编码帧中每个宏块的类型信息。在 H.264/AVC 视频编解码过程中，一帧图像会被分割成若干个宏块，每个宏块都有不同的类型，根据宏块的类型可以采用不同的编码方法。mb_type 数组则用来存储每个宏块的类型。在编码过程中，会根据当前宏块之前的参考帧来决定当前宏块的类型，所以 mb_type 数组是在编码过程中动态生成的，存储的是当前帧中每个宏块的类型。在解码过程中，解码器会根据 mb_type 数组解码出每个宏块的类型信息，并采用相应的解码方式进行解码。*/
    int8_t  *mb_type;
    /*x264_frame_t 结构体中还有一个 uint8_t *mb_partition 成员变量，用于存储每个宏块中的子块划分信息。在 H.264/AVC 视频编解码中，每个宏块都可以被划分成多个子块，每个子块也有不同的类型，比如 4x4 块、8x8 块等。mb_partition 数组用于记录每个宏块中的子块类型和位置信息，以便于编码和解码过程中进行相应的操作。

mb_partition 数组中每一个字节存储一个宏块中一个子块的信息，每个宏块中的子块信息存储顺序从左到右、从上到下。具体来说，一个字节的最高2个比特位表示当前宏块中子块的类型，后6个比特位表示当前子块在宏块中的位置信息。对于一个宏块而言，其子块的类型和位置信息都是固定的，因此 mb_partition 数组只需要在开始编码时生成一次即可，无需在编码过程中动态生成。*/
    uint8_t *mb_partition;
    /*int16_t (*mv[2])[2] 中第一个 2 表示 mv 是一个指向 int16_t (*)[2] 数组的指针数组。

int16_t (*)[2] 表示一个指针，它指向一个一维数组，这个一维数组中包含两个元素，每个元素都是 int16_t 类型的变量，可以用来存储一个宏块的运动矢量。而 mv 是一个指向指针数组的指针，也就是说 mv 是一个数组，每一个元素都是一个指向 int16_t [][2] 数组的指针，这个数组中包含了一帧图像中所有宏块的运动矢量信息。

具体来说，mv[0] 存储当前帧中所有宏块在 X 方向的运动矢量，而 mv[1] 则存储所有宏块在 Y 方向的运动矢量，每个 mv[i] 数组元素实际上指向了一个一维数组，这个数组中包含了所有宏块在 i 方向上的运动矢量信息，也就是说，对于一个宏块的运动矢量，通过 mv[i][j][0] 可以找到其在 i 方向上的偏移量，而通过 mv[i][j][1] 则可以找到其在 j 方向上的偏移量。*/
    int16_t (*mv[2])[2];

    /*int16_t (*mv16x16)[2]; 是 x264_picture_t 结构体中的一个成员变量，它是一个指向数组的指针，其中数组元素为一个由两个 int16_t 类型变量构成的数组，用于存储一帧图像中 16x16 块的运动矢量。

与 mv[2][16][16][2] 不同的是，mv16x16 只存储一帧图像中所有 16x16 块的运动矢量信息，因为 16x16 块是整个图像中最大的宏块，而 mv 则存储了整个图像中所有宏块的运动矢量信息。

在运动补偿预测中，对于每个 16x16 块，我们需要用先前编码过的图像数据来预测当前帧中每个像素的值，所以需要知道当前 16x16 块的运动矢量。与其他宏块相同，当前 16x16 块的运动矢量可以使用之前编码的参考帧和当前帧中的差帧来计算，因此解码端需要准确获取上一帧图像中每个 16x16 块的运动矢量，如果当前帧和参考帧中相应的 16x16 块的相对位置相同，那么当前帧中对应的 16x16 块的运动矢量就可以通过 mv16x16 数组中对应位置的元素来获得。*/
    int16_t (*mv16x16)[2];
    /*在x264_frame_t结构体中，int16_t (*lowres_mvs[2][X264_BFRAME_MAX+1])[2]是一个指向指针数组的指针。

具体来说，x264_frame_t是一个存储视频帧数据的结构体，lowres_mvs是其中一个成员，它表示图像的下采样运动向量信息。

lowres_mvs是一个二维数组，第一维大小为2，第二维大小为X264_BFRAME_MAX+1。其中2表示两个参考帧，因为x264编码器使用多帧参考技术；X264_BFRAME_MAX+1表示每帧的最大B帧数。

lowres_mvs的每个元素都是一个指针，指向一个长度为2的int16_t数组，存储该帧图像的所有运动向量信息。具体来说，该数组的第一个元素表示水平方向的运动向量，第二个元素表示垂直方向的运动向量。

因此，int16_t (*lowres_mvs[2][X264_BFRAME_MAX+1])[2]可以理解为一个指针数组的指针，指向大小为2的指针数组，每个指针又指向大小为2的int16_t数组。*/
    int16_t (*lowres_mvs[2][X264_BFRAME_MAX+1])[2];
    /*在x264_frame_t结构体中，uint8_t *field 是一个指向当前帧图片的数据的指针。

具体来说，x264_frame_t是一个描述视频帧信息的结构体，它包含了一系列成员变量来描述当前帧的各种属性，其中field表示当前帧的像素数据。

这里的field是一个指针，指向当前帧的图像数据。uint8_t是无符号8位整型，表示每个像素的取值范围在0~255之间。由于每个像素占用1个字节，因此指针可以用来访问存储在当前帧中的图片数据。

通过访问field指针，可以获取单个像素的值，并进行计算、处理和渲染等操作。因此，field指针是x264编码器中非常重要的一个成员，对于视频编解码流程有着至关重要的作用。*/
    uint8_t *field;
    /*在x264_frame_t结构体中，uint8_t *effective_qp 是一个指向当前帧实际使用的量化参数（QP）数据的指针。

具体来说，x264_frame_t是一个描述视频帧信息的结构体，它包含了一系列成员变量来描述当前帧的各种属性，其中effective_qp表示当前帧实际使用的量化参数数据。

在x264编码器中，量化参数（QP）是一种对视频帧进行压缩的重要参数，用于调整视频帧各个宏块的压缩效率，从而在保证视频质量的前提下，提高视频编码的压缩率。effective_qp指针记录了当前帧实际使用的量化参数数据，即该帧中每个宏块对应的QP值。

通过访问effective_qp指针，可以获取当前帧中每个宏块的QP值，从而进行二次编码、质量控制、码流控制等操作。因此，effective_qp指针是x264编码器中非常重要的一个成员，对于视频编解码流程有着至关重要的作用。*/
    uint8_t *effective_qp;

    /* Stored as (lists_used << LOWRES_COST_SHIFT) + (cost).
     * Doesn't need special addressing for intra cost because
     * lists_used is guaranteed to be zero in that cast. */
    /*在x264_frame_t结构体中，uint16_t (*lowres_costs[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]) 是一个指向二维数组的指针，用于存储图像下采样帧间预测的相关信息。

具体来说，x264_frame_t是一个存储视频帧数据的结构体，lowres_costs是其中一个成员，它表示下采样帧间预测时，不同参考帧之间的像素差异。

lowres_costs是一个二维数组，第一维和第二维大小均为X264_BFRAME_MAX+2，其中X264_BFRAME_MAX表示每个参考帧所能用的最大B帧数。+2是因为在低分辨率下，每个参考帧还可以使用之前第一帧或第二帧进行预测。

lowres_costs的每个元素都是一个指针，指向长度为2的uint16_t数组，在低分辨率下存储当前参考帧和其他参考帧之间的像素差值。具体来说，该数组的第一个元素表示水平方向的像素差值，第二个元素表示垂直方向的像素差值。

因此，uint16_t (*lowres_costs[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]) 可以理解为一个指针数组的指针，指向大小为X264_BFRAME_MAX+2的指针数组，每个指针又指向大小为2的uint16_t数组，存储当前参考帧和其他参考帧之间的像素差值。*/
    uint16_t (*lowres_costs[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]);
    #define LOWRES_COST_MASK ((1<<14)-1)
    #define LOWRES_COST_SHIFT 14

    /*在x264_frame_t结构体中，int *lowres_mv_costs[2][X264_BFRAME_MAX+1] 是一个指向二维数组的指针，用于存储图像下采样时运动矢量的成本信息。

具体来说，x264_frame_t是一个存储视频帧数据的结构体，lowres_mv_costs是其中一个成员，它表示图像下采样时使用的运动矢量的成本。

lowres_mv_costs是一个二维数组，第一维大小为2，表示两个参考帧；第二维大小为X264_BFRAME_MAX+1，表示当前帧中最大的B帧数。

lowres_mv_costs的每个元素都是一个指针，指向一个int类型的数组，表示使用当前参考帧和其他参考帧进行预测时的运动矢量成本。

因此，int *lowres_mv_costs[2][X264_BFRAME_MAX+1] 可以理解为一个指针数组的指针，指向大小为2的指针数组，每个指针又指向长度为X264_BFRAME_MAX+1的int类型数组，存储当前参考帧和其他参考帧预测时的运动矢量成本。*/
    int     *lowres_mv_costs[2][X264_BFRAME_MAX+1];
    /*在x264_frame_t结构体中，int8_t *ref[2] 是一个指向二维数组的指针，用于存储当前帧参考帧的信息。

具体来说，x264_frame_t是一个存储视频帧数据的结构体，ref是其中一个成员，它表示当前帧的参考帧信息。

ref是一个二维数组，第一维大小为2，表示两个参考帧；第二维大小不固定，表示参考帧的长度。

ref的每个元素都是一个指针，指向表示参考帧数据的int8_t类型的数组，用于存储当前帧参考帧的数据。

因此，int8_t *ref[2] 可以理解为一个指针数组，指向大小为2的int8_t类型数组，用于存储当前帧参考帧的数据。通过访问ref指针，可以获取当前帧的参考帧数据，并在视频编码过程中进行运算和处理。*/
    int8_t  *ref[2];
    /*在x264_frame_t结构体中，int i_ref[2] 表示当前帧参考帧的索引信息。

具体来说，x264_frame_t是一个存储视频帧数据的结构体，i_ref是其中一个成员，它表示当前帧所使用的参考帧的索引信息。

i_ref是一个int类型的数组，大小为2，表示当前帧所使用的参考帧的索引。x264编码器支持多帧参考技术，因此在编码过程中，当前帧可能会参考前面若干帧的图像数据。

通过访问i_ref数组，可以获取当前帧所使用的参考帧的索引号，从而确定当前帧需要参考哪些前面的帧。因此，i_ref数组对于图像编码的过程具有重要的作用。*/
    int     i_ref[2];
    /*这个变量是x264视频编码器中的关键变量之一，它用于存储参考帧的POC（Picture Order Count）值。POC是指在编码过程中为视频帧分配的序号，它有助于在解码过程中正确地重建编码帧的顺序和图像质量。ref_poc[2][X264_REF_MAX]规定了每个参考帧的POC值，并且它可以通过编码器的各种配置选项进行修改，以调整编码的性能和质量。
    在x264_frame_t结构体中，ref_poc[2][X264_REF_MAX]是一个二维数组，它有两个维度。第一个维度是2，表示参考帧分为两类：前向参考帧和后向参考帧。第二个维度是X264_REF_MAX，表示每个参考帧都有一个对应的索引值，该索引值最大为X264_REF_MAX。因此，ref_poc[0][i]和ref_poc[1][i]分别表示第i个前向参考帧和第i个后向参考帧的POC值。*/
    int     ref_poc[2][X264_REF_MAX];
    /*在x264视频编码器中，x264_frame_t结构体中的inv_ref_poc[2]变量是一个长度为2的数组，用于存储两个参考帧的POC反序变换值。POC反序变换是一种算法，它将参考帧的POC值从正序变为反序，并将结果存储在inv_ref_poc数组中。这个反序变换值通常用于解码器中，以帮助解码器正确地重建原始视频流。inv_ref_poc[0]和inv_ref_poc[1]分别存储了前向参考帧和后向参考帧的反序变换值，它们都是16位整数类型int16_t。*/
    int16_t inv_ref_poc[2]; // inverse values of ref0 poc to avoid divisions in temporal MV prediction

    /* for adaptive B-frame decision.
     * contains the SATD cost of the lowres frame encoded in various modes
     * FIXME: how big an array do we need? */
    /*在x264视频编码器中，x264_frame_t结构体中的i_cost_est[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]变量是一个二维数组，用于存储B帧编码时的参考帧选择代价值。B帧是一种双向预测帧，它前后都有参考帧，因此编码时需要选择适当的参考帧来确保编码效率和图像质量。i_cost_est数组通过预测参考帧的变化来计算参考帧选择的代价值。其第一个维度是X264_BFRAME_MAX+2，表示每个B帧最多有X264_BFRAME_MAX个参考帧。第二个维度也是X264_BFRAME_MAX+2，表示每个参考帧也最多可以被X264_BFRAME_MAX个B帧引用。因此，i_cost_est[x][y]表示使用第x个B帧作为当前编码帧，引用第y个参考帧的代价值。*/
    int     i_cost_est[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2];
    /*在x264视频编码器中，x264_frame_t结构体中的i_cost_est_aq[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]变量是一个二维数组，用于存储使用自适应量化(AQ)模式时的参考帧选择代价值。自适应量化是一种用于提高视频编码质量和减少码率的技术，它将量化因子根据图像细节进行动态调整。i_cost_est_aq数组中的每个元素表示使用第x个B帧，并引用第y个参考帧的代价值，用于调整AQ模式中的参考帧选择。该数组和i_cost_est数组的作用类似，只不过它是在AQ模式下使用的，以提高编码效率和图像质量。*/
    int     i_cost_est_aq[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2];
    /*在x264视频编码器中，x264_frame_t结构体中的i_satd变量是一个整型变量，用于存储一个宏块的鲨鱼距离(SAD)的变换系数和。SAD是指两个图像块像素之间的绝对差值的和，鲨鱼距离是指SAD和的变换系数和。它用于评估编码器在进行块级别的运动估计和预测时的性能和准确度。在编码过程中，编码器将会尝试多种运动矢量和预测模式，通过计算不同预测模式下的鲨鱼距离和变换系数和来选择最佳的编码方式。i_satd存储了计算得到的SAD的变换系数和值，其数值越小表示编码效果越好。*/
    int     i_satd; // the i_cost_est of the selected frametype
    /*在x264视频编码器中，x264_frame_t结构体中的i_intra_mbs[X264_BFRAME_MAX+2]变量是一个整型数组，用于存储B帧中的内部宏块数目。B帧是一个双向预测帧，它前后都有参考帧，并且在B帧中也会使用内部预测模式。内部预测模式是指利用帧内已有的像素数据进行预测，而不是利用参考帧进行预测。i_intra_mbs[x]表示第x个B帧中使用内部预测模式的宏块数目，用于评估B帧的编码效率和图像质量。此外，i_intra_mbs[0]和i_intra_mbs[1]分别表示最新和次新的参考帧的内部宏块数目。*/
    int     i_intra_mbs[X264_BFRAME_MAX+2];
    /*在x264视频编码器中，x264_frame_t结构体中的i_row_satds[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2]是一个三维指针数组，用于存储B帧中用于编码一个宏块的每个16x16宏块的鲨鱼距离(SAD)和。其第一维表示第几个B帧，最多有X264_BFRAME_MAX+2个参考帧，第二维用于表示参考帧的数量，同样最多有X264_BFRAME_MAX+2个参考帧，第三维表示了当前宏块在该B帧中的16x16块的数量，该数量就是在宏块中最多能包含多少个16x16宏块。因此，i_row_satds[x][y][z]表示第x个B帧的第y个参考帧中第z个16x16宏块的鲨鱼距离和。SAD是指两个图像块像素之间的绝对差值的和，鲨鱼距离是指SAD和的变换系数和。在编码过程中，编码器会对当前宏块的不同16x16分块方式下的SAD和进行计算和比较，以求出最优的编码方式。i_row_satds数组存储了这些16x16块的SAD和，从而支持最优预测模式的选取和编码。*/
    int     *i_row_satds[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2];
    // 该变量表示编码帧中每一行的空间域变换误差和(SATD)值，SATD值是衡量帧编码质量的一项重要指标，它可以通过变换算法计算出来。 
    int     *i_row_satd;
    // 该变量表示每一行经过编码后的比特数，它可以通过编码器的码率控制算法来控制，以达到预期的视频压缩比和视频质量。
    int     *i_row_bits;
    // 该变量表示编码帧中每一行的量化参数QP值，它是用来控制宏块在编码过程中的压缩程度，以便达到视频质量和码率之间的平衡。
    float   *f_row_qp;
    // 该变量表示编码帧中每一行的量化参数Qscale值，它是和QP值相对应的一种衡量压缩程度的指标，通过Qscale值可以控制宏块在编码过程中的压缩程度。 
    float   *f_row_qscale;
    // 该变量表示编码帧中所有宏块的QP偏移量，QP偏移量可以用来调整编码质量和压缩比之间的平衡。 
    float   *f_qp_offset;
    // 该变量表示编码帧中所有宏块的自适应量化(AQ)的QP偏移量，AQ技术可以根据宏块的复杂度自动调整宏块的量化参数以获得更好的编码质量和压缩比之间的平衡。
    float   *f_qp_offset_aq;
    // 该变量表示编码器是否已经计算出该帧的帧内帧，帧内帧是视频编码中的一种关键帧，通常用于表示视频序列中的静态或缓慢变化的部分，在视频解码过程中可以独立解码。
    int     b_intra_calculated;
    // 该变量表示编码帧中每一个宏块的帧内代价，它是衡量编码质量的另一个重要指标，它可以在编码过程中用来控制视频质量和码率之间的平衡。 
    uint16_t *i_intra_cost;
    /*在x264视频编码器中，x264_frame_t结构体中的i_propagate_cost是一个指向uint16_t数组的指针，用于存储因编码丢失而导致的宏块失真影响的传播代价。i_propagate_cost数组的每个元素代表了相应宏块的传播代价值。在视频编码中，编码器为了达到更好的压缩效果，通常会对一个宏块进行预测编码，并在该宏块被解码时，将预测值传递给它周围的宏块。但是，如果有一个或多个宏块的编码数据丢失，那么它周围宏块的预测值就会受到影响，导致这些宏块的失真增加。在这种情况下，i_propagate_cost变量可以用于表示每个宏块传播失真的代价，它的值越大，说明传播失真越严重。经过计算，编码器将会尝试选择一种有利于该宏块的传播方式，并将其存储到i_propagate_cost数组中。*/
    uint16_t *i_propagate_cost;
    /*在x264视频编码器中，x264_frame_t结构体中的i_inv_qscale_factor是一个指向uint16_t数组的指针，用于存储反比例量化因子。量化是视频编码中的一个关键过程，它会将图像数据进行变换压缩，从而减小数据量。反比例量化因子是指量化过程中使用的一个值，它会影响到图像数据的变换程度，从而影响了图像的质量和编码的码率。i_inv_qscale_factor数组中的每个元素代表了相应宏块的反比例量化因子，具体数值取决于编码器的各种配置选项。

在编码过程中，编码器会尝试多种量化和反量化方式，并通过调节反比例量化因子来得到最优的编码效果。反比例量化因子越小，说明量化程度越高、图像质量越差、码率越小。而反比例量化因子越大，则说明量化程度越小、图像质量越好、码率越大。对于不同的场景和编码质量需求，可以通过调节反比例量化因子来进行自适应变换，以达到更好的编码效果和图像质量。*/
    uint16_t *i_inv_qscale_factor;
    // 用于标记该帧是否为真正的场景切换帧。如果该值为0，则说明该帧不是场景切换帧。 
    int     b_scenecut; /* Set to zero if the frame cannot possibly be part of a real scenecut. */

    float   f_weighted_cost_delta[X264_BFRAME_MAX+2];
    // 用于存储该帧图像的像素和。该变量的数据类型是uint32_t，可以存储2^32-1个非负整数。
    // 3：y/u/v
    uint32_t i_pixel_sum[3];
    // 用于存储该帧图像的像素总方差。该变量的数据类型是uint64_t，可以存储2^64-1个非负整数。 
    // 3：y/u/v
    uint64_t i_pixel_ssd[3];

    /* hrd */
    // 变量类型为x264_hrd_t结构体，表示视频编码中的比特率控制相关的信息。HRD即Hypothetical Reference Decoder，是一种指定码率控制参数的方法。通过控制码率，可以控制图像的质量和文件大小，以适应不同场景的需求。
    x264_hrd_t hrd_timing;

    /* vbv */
    // 类型为uint8_t的数组，表示预测的编码类型。x264是一种自适应视频编码器，它可以自动选择编码类型，以达到最佳的压缩效果。在编码过程中，x264将预测图像的编码类型，以提高编码效率。
    uint8_t i_planned_type[X264_LOOKAHEAD_MAX+1];
    // 类型为int的数组，表示预测的帧的SAD（Sum of Absolute Difference）值。SAD是用来计算两帧之间的相似度的指标，它可以用来评估预测图像质量。
    int i_planned_satd[X264_LOOKAHEAD_MAX+1];
    // 类型为double的数组，表示预测的码流缓冲时间。码流缓冲时间指的是在标准场景下视频编码输出的码流所需的时间。x264会自动调整编码参数，以避免缓冲时间过长或过短。
    double f_planned_cpb_duration[X264_LOOKAHEAD_MAX+1];
    // 类型为int64_t的变量，表示已编码的帧的数量。x264采用帧内编码和帧间编码相结合的方式，需要对已编码的帧进行计数，以便正确预测下一帧的编码方式。
    int64_t i_coded_fields_lookahead;
    // 类型为int64_t的变量，表示预测的码率控制值。码率控制值是用来控制编码输出速度和输出质量的参数。x264在编码过程中会根据这个参数来调整编码器的行为。
    int64_t i_cpb_delay_lookahead;

    /* threading */
    // 类型为int的变量，表示已经编码完成的像素行数。x264采用逐行扫描的方式进行编码，所以需要对已经编码完成的像素行数进行计数。
    int     i_lines_completed; /* in pixels */
    // 类型为int的变量，表示像素行的权重。x264可以根据像素行的权重来调整编码参数，以达到更好的编码效果。
    int     i_lines_weighted; /* FIXME: this only supports weighting of one reference frame */
    // 正在使用此帧的线程数
    int     i_reference_count; /* number of threads using this frame (not necessarily the number of pointers) */
    x264_pthread_mutex_t mutex;
    x264_pthread_cond_t  cv;
    // 类型为int的变量，表示当前帧的切片数量。x264在编码时会将一帧划分为多个切片，以提高编码效率和质量。该变量用于记录当前帧的切片数量。
    int     i_slice_count; /* Atomically written to/read from with slice threads */

    /* periodic intra refresh */
    // 类型为float的变量，表示调整帧内刷新的时间点。帧内刷新是一种编码技术，用于去除图像序列中的冗余数据。该变量用于指定帧内刷新的时间点。
    float   f_pir_position;
    // 类型为int的变量，表示帧内刷新开始的列数。该变量用于指定帧内刷新的区域。
    int     i_pir_start_col;
    // 类型为int的变量，表示帧内刷新结束的列数。该变量用于指定帧内刷新的区域。
    int     i_pir_end_col;
    // 类型为int的变量，表示从上一次帧内刷新后的编码帧数。该变量用于判断何时进行帧内刷新
    int     i_frames_since_pir;

    /* interactive encoder control */
    // 类型为int的变量，表示表明此帧是否是损坏帧。损坏帧指的是在编码或解码过程中出现错误的图像帧。
    int     b_corrupt;

    /* user sei */
    // 类型为x264_sei_t结构体，表示用户可定义的视频编码后附加的信息。SEI（Supplemental Enhancement Information）是一种用于视频附加信息的标准。
    x264_sei_t extra_sei;

    /* user data */
    // 类型为void指针的变量，表示缓存用户自定义的数据。该变量用于存储用户自定义的数据，比如事件处理程序、回调函数等等。
    void *opaque;

    /* user frame properties */
    // 类型为uint8_t指针的变量，表示宏块的相关信息。宏块是视频编码的基本单位，x264在编码过程中会生成宏块信息，在解码过程中使用。
    uint8_t *mb_info;
    void (*mb_info_free)( void* );

#if HAVE_OPENCL
    x264_frame_opencl_t opencl;
#endif
} x264_frame_t;

/* synchronized frame list */
typedef struct
{
   x264_frame_t **list;
   int i_max_size;
   int i_size;
   x264_pthread_mutex_t     mutex;
   x264_pthread_cond_t      cv_fill;  /* event signaling that the list became fuller */
   x264_pthread_cond_t      cv_empty; /* event signaling that the list became emptier */
} x264_sync_frame_list_t;

typedef void (*x264_deblock_inter_t)( pixel *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 );
typedef void (*x264_deblock_intra_t)( pixel *pix, intptr_t stride, int alpha, int beta );
typedef struct
{
    x264_deblock_inter_t deblock_luma[2];
    x264_deblock_inter_t deblock_chroma[2];
    x264_deblock_inter_t deblock_h_chroma_420;
    x264_deblock_inter_t deblock_h_chroma_422;
    x264_deblock_intra_t deblock_luma_intra[2];
    x264_deblock_intra_t deblock_chroma_intra[2];
    x264_deblock_intra_t deblock_h_chroma_420_intra;
    x264_deblock_intra_t deblock_h_chroma_422_intra;
    x264_deblock_inter_t deblock_luma_mbaff;
    x264_deblock_inter_t deblock_chroma_mbaff;
    x264_deblock_inter_t deblock_chroma_420_mbaff;
    x264_deblock_inter_t deblock_chroma_422_mbaff;
    x264_deblock_intra_t deblock_luma_intra_mbaff;
    x264_deblock_intra_t deblock_chroma_intra_mbaff;
    x264_deblock_intra_t deblock_chroma_420_intra_mbaff;
    x264_deblock_intra_t deblock_chroma_422_intra_mbaff;
    void (*deblock_strength)( uint8_t nnz[X264_SCAN8_SIZE], int8_t ref[2][X264_SCAN8_LUMA_SIZE],
                              int16_t mv[2][X264_SCAN8_LUMA_SIZE][2], uint8_t bs[2][8][4], int mvy_limit,
                              int bframe );
} x264_deblock_function_t;

#define x264_frame_delete x264_template(frame_delete)
void          x264_frame_delete( x264_frame_t *frame );

#define x264_frame_copy_picture x264_template(frame_copy_picture)
int           x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src );

#define x264_frame_expand_border x264_template(frame_expand_border)
void          x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y );
#define x264_frame_expand_border_filtered x264_template(frame_expand_border_filtered)
void          x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end );
#define x264_frame_expand_border_lowres x264_template(frame_expand_border_lowres)
void          x264_frame_expand_border_lowres( x264_frame_t *frame );
#define x264_frame_expand_border_chroma x264_template(frame_expand_border_chroma)
void          x264_frame_expand_border_chroma( x264_t *h, x264_frame_t *frame, int plane );
#define x264_frame_expand_border_mod16 x264_template(frame_expand_border_mod16)
void          x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame );
#define x264_expand_border_mbpair x264_template(expand_border_mbpair)
void          x264_expand_border_mbpair( x264_t *h, int mb_x, int mb_y );

#define x264_frame_deblock_row x264_template(frame_deblock_row)
void          x264_frame_deblock_row( x264_t *h, int mb_y );
#define x264_macroblock_deblock x264_template(macroblock_deblock)
void          x264_macroblock_deblock( x264_t *h );

#define x264_frame_filter x264_template(frame_filter)
void          x264_frame_filter( x264_t *h, x264_frame_t *frame, int mb_y, int b_end );
#define x264_frame_init_lowres x264_template(frame_init_lowres)
void          x264_frame_init_lowres( x264_t *h, x264_frame_t *frame );

#define x264_deblock_init x264_template(deblock_init)
void          x264_deblock_init( int cpu, x264_deblock_function_t *pf, int b_mbaff );

#define x264_frame_cond_broadcast x264_template(frame_cond_broadcast)
void          x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed );
#define x264_frame_cond_wait x264_template(frame_cond_wait)
void          x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed );
#define x264_frame_new_slice x264_template(frame_new_slice)
int           x264_frame_new_slice( x264_t *h, x264_frame_t *frame );

#define x264_threadslice_cond_broadcast x264_template(threadslice_cond_broadcast)
void          x264_threadslice_cond_broadcast( x264_t *h, int pass );
#define x264_threadslice_cond_wait x264_template(threadslice_cond_wait)
void          x264_threadslice_cond_wait( x264_t *h, int pass );

#define x264_frame_push x264_template(frame_push)
void          x264_frame_push( x264_frame_t **list, x264_frame_t *frame );
#define x264_frame_pop x264_template(frame_pop)
x264_frame_t *x264_frame_pop( x264_frame_t **list );
#define x264_frame_unshift x264_template(frame_unshift)
void          x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame );
#define x264_frame_shift x264_template(frame_shift)
x264_frame_t *x264_frame_shift( x264_frame_t **list );
#define x264_frame_push_unused x264_template(frame_push_unused)
void          x264_frame_push_unused( x264_t *h, x264_frame_t *frame );
#define x264_frame_push_blank_unused x264_template(frame_push_blank_unused)
void          x264_frame_push_blank_unused( x264_t *h, x264_frame_t *frame );
#define x264_frame_pop_blank_unused x264_template(frame_pop_blank_unused)
x264_frame_t *x264_frame_pop_blank_unused( x264_t *h );
#define x264_weight_scale_plane x264_template(weight_scale_plane)
void x264_weight_scale_plane( x264_t *h, pixel *dst, intptr_t i_dst_stride, pixel *src, intptr_t i_src_stride,
                              int i_width, int i_height, x264_weight_t *w );
#define x264_frame_pop_unused x264_template(frame_pop_unused)
x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec );
#define x264_frame_delete_list x264_template(frame_delete_list)
void          x264_frame_delete_list( x264_frame_t **list );

#define x264_sync_frame_list_init x264_template(sync_frame_list_init)
int           x264_sync_frame_list_init( x264_sync_frame_list_t *slist, int nelem );
#define x264_sync_frame_list_delete x264_template(sync_frame_list_delete)
void          x264_sync_frame_list_delete( x264_sync_frame_list_t *slist );
#define x264_sync_frame_list_push x264_template(sync_frame_list_push)
void          x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame );
#define x264_sync_frame_list_pop x264_template(sync_frame_list_pop)
x264_frame_t *x264_sync_frame_list_pop( x264_sync_frame_list_t *slist );

#endif
